package com.luoyulin.linkedlist;

import com.sun.org.apache.xpath.internal.WhitespaceStrippingElementMatcher;
import javafx.application.Preloader;

import java.awt.*;
import java.util.Stack;

/**
 * @author luoyulin
 * @create 2021-12-26 21:29
 **/
public class SingleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "骆鱼鳞", "笑傲可爱");
        HeroNode hero3 = new HeroNode(3, "邱老板", "妹妹");
        HeroNode hero4 = new HeroNode(4, "大哥哥", "帅哥");
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero2);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero4);
        singleLinkedList.showList();
//        singleLinkedList.addByOrder(hero1);
//        singleLinkedList.addByOrder(hero2);
//        singleLinkedList.addByOrder(hero2);
//        singleLinkedList.addByOrder(hero4);
//        singleLinkedList.showList();
//        System.out.println();
//        //测试修改节点的代码
//        HeroNode newHeroNode = new HeroNode(2, "骆琳琳", "大哥");
//        singleLinkedList.update(newHeroNode);
//        singleLinkedList.showList();
//        System.out.println();
//        //删除一个节点
//        singleLinkedList.delet(2);
//        singleLinkedList.showList();
//        //获取长度
//        System.out.println(getLength(singleLinkedList.getHead()));
//        HeroNode res = findLastIndexNode(singleLinkedList.getHead(),1);
//        System.out.println(res);

        //单链表反转
        reverseList(singleLinkedList.getHead());
        System.out.println();
        singleLinkedList.showList();
        //逆序打印 不改变链表本身结构
        System.out.println();
        reversePrint(singleLinkedList.getHead());
    }

    //获取单链表的节点个数（如果带头节点，需要不统计头节点）
    public static int getLength(HeroNode heroNode){
        if(heroNode.next == null){
            return 0;
        }
        int length = 0;
        HeroNode cur = heroNode.next;//没有统计头节点
        while (cur != null){
            length++;
            cur = cur.next;
        }
        return length;
    }

    public static HeroNode findLastIndexNode(HeroNode head,int index){
        if(head.next == null){
            return null;//没有找到
        }
        int size = getLength(head); //得到长度
        //遍历size-index位置
        if(index <= 0 || index > size){
            return null;
        }
        HeroNode cur = head.next;
        for (int i = 0; i < size - index; i++) {
            cur = cur.next;
        }
        return cur;
    }
    //链表的反转
    public static void reverseList(HeroNode head){
        if(head.next == null || head.next.next == null){
            return;
        }
        //定义一个辅助指针
        HeroNode cur = head.next;
        HeroNode next = null;//指向当前节点的下一个节点
        HeroNode reverseHead = new HeroNode(0,"","");
        //遍历原来的链表
        while(cur!= null){
            next = cur.next;//保存当前节点的下一个节点
            cur.next = reverseHead.next;//将cur的下一个节点指向新链表的最前面
            reverseHead.next = cur;
            cur = next;//cur后移
        }
        head.next = reverseHead.next;//实现反转
    }

    //逆序打印单链表（将各个节点压入栈，利用先进后出的特点打印）

    public static void reversePrint(HeroNode head){
        if(head.next == null){
            System.out.println("空链表");
        }
        //创建一个栈
        Stack<HeroNode> stack = new Stack<HeroNode>();
        HeroNode cur = head.next;
        //将链表中的所有节点压入栈
        while (cur != null){
            stack.push(cur);
            cur = cur.next; //压入下一个节点
        }
        while (stack.size() > 0){
            System.out.println(stack.pop());//先进后出
        }
    }

    //合并两个链表，合并后依然有序
    public static void mergeTwoList(HeroNode h1,HeroNode h2){
        if(h1.next == null || h2.next ==null){

        }
    }

}

//定义一个单链表
class SingleLinkedList {
    //初始化头节点
    private HeroNode head = new HeroNode(0, "", "");

    public HeroNode getHead() {
        return head;
    }

    //添加
    public void add(HeroNode heroNode) {
        //辅助变量
        HeroNode temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;
    }


    public void showList() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.next;
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }

//按照编号进行添加
    public void addByOrder(HeroNode heroNode){
        //
        HeroNode temp = head;
        boolean flag = false;//添加的编号是否存在
        while (true){
            if(temp.next == null){//到最后
                break;
            }
            if(temp.next.no > heroNode.no){
                break;
            } else if (temp.next.no == heroNode.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            System.out.printf("%d已存在\n",heroNode.no);
        }else{
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }
    //修改节点的信息，根据NO编号来修改，即no编号不能改
    public void update(HeroNode heroNode){
        if(head.next == null){
            System.out.println("链表为空。");
            return;
        }
        HeroNode temp = head.next;
        boolean flag = false;
        while (true){
            if(temp == null){
                break;//链表遍历结束
            }
            if(temp.no == heroNode.no){
                //找到了
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag是否找到修改的节点
        if(flag){
            temp.name = heroNode.name;
            temp.nickName = heroNode.nickName;
        }else{
            System.out.printf("没有找到编号维%d的节点，不能修改\n",heroNode.no);
        }
    }

    public void delet(int no){
        HeroNode temp = head;
        boolean flag = false;
        while (true){
            if(temp.next == null){
                break;
            }
            if(temp.next.no == no){
                //找到了待删除节点的前一个节点
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.next = temp.next.next;
        } else{
            System.out.println("找不到节点，无法删除");
        }
    }

}

//定义一个HeroNode
class HeroNode{
    public int no;
    public String name;
    public String nickName;
    public HeroNode next;

    public HeroNode(int hNo,String hName,String hNickName){
        this.no = hNo;
        this.name = hName;
        this.nickName = hNickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }

}